/**
 * @file renorm_custom_tiling.cpp
 *
 * Copyright (C) 2025. Huawei Technologies Co., Ltd. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
#include <cassert>
#include <cstddef>
#include "renorm_custom_tiling.h"
 #include <cstdio>
// bfloat16, float16, float
constexpr uint32_t DATA_TYPE_SIZE[] = {2, 2, 4};
constexpr uint32_t BLOCK_SIZE = 32;
constexpr uint32_t BUFFER_NUM = 1;
//constexpr uint32_t UB_BLOCK_NUM = 100; // 一个块可以处理的最大datablock数量
//constexpr uint32_t MAX_AVAILABLE_UB_BLOCK_NUM = UB_BLOCK_NUM / BUFFER_NUM * BUFFER_NUM;

// tiling参数计算函数
//void TilingParamsCalc(uint32_t length, uint32_t alignNum,
//                      uint32_t &tileNum, uint32_t &tileLength, uint32_t &lastTileLength)
//{
//    assert(alignNum != 0U);
//    tileNum = length / (alignNum * MAX_AVAILABLE_UB_BLOCK_NUM);
//    if ((static_cast<uint32_t>(length / alignNum) % MAX_AVAILABLE_UB_BLOCK_NUM == 0U) || tileNum == 0U)
//    {
//        if (tileNum == 0U)
//        {
//            tileNum = 1U;
//        }
//        if (length < MAX_AVAILABLE_UB_BLOCK_NUM * alignNum)
//        {
//            tileLength = ((static_cast<size_t>(length) / alignNum) + 1) / BUFFER_NUM * BUFFER_NUM * alignNum;
//            lastTileLength = tileLength;
//        }
//        else
//        {
//            tileLength = MAX_AVAILABLE_UB_BLOCK_NUM * alignNum;
//            lastTileLength = (uint32_t)(length - (tileNum - 1) * tileLength);
//        }
//    }
//    else
//    {
//        tileNum++;
//        tileLength = MAX_AVAILABLE_UB_BLOCK_NUM * alignNum;
//        lastTileLength = (uint32_t)(length - (tileNum - 1) * tileLength);
//    }
//}

void GenerateTilingData(uint8_t *tilingBuf, uint32_t & blockDim, uint32_t dim)
{
  	RenormCustomTilingData *tiling = reinterpret_cast<RenormCustomTilingData *>(tilingBuf);
    uint32_t rawNum;
    uint32_t columnNum;
    uint32_t dataTypeSize;

    rawNum = tiling->rawNum;
    columnNum = tiling->columnNum;
	dataTypeSize = DATA_TYPE_SIZE[tiling->dataType];
    if (dim == 0)
    {
        // 核心数大于操作数
        if (rawNum < blockDim)
        {
          	blockDim = rawNum;
        }
        // tilling不对齐
        if (((tiling->columnNum * dataTypeSize) % BLOCK_SIZE) == 0)
        {
          	tiling->alignFlag = 1;
            tiling->tileLength = columnNum;
        }
        else{
            tiling->alignFlag = 0;
            uint32_t alignNum = (BLOCK_SIZE - (columnNum * dataTypeSize) % BLOCK_SIZE) / dataTypeSize;
            tiling->tileLength = columnNum + alignNum;//111
        }

      	tiling->tileNum = rawNum / blockDim;
        tiling->blockLength = tiling->tileNum * tiling->columnNum;
        tiling->tailNum = tiling->tileNum + (rawNum % blockDim);

    }
    else if (dim == 1)
    {
      	// 核心数大于操作数
      	if (columnNum < blockDim)
        {
          	blockDim = columnNum;
        }
		tiling->tileNum = columnNum / blockDim;
        tiling->tileLength = rawNum;
        tiling->blockLength = tiling->tileNum * tiling->tileLength;
        tiling->tailNum = tiling->tileNum + (columnNum % blockDim);
    }
	tiling->EvenCore = blockDim - 1; // 最后一个核的id

}